/* Copyright 2009 Sony Mathew, Minneapolis MN. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at  http://www.apache.org/licenses/LICENSE-2.0  Unless required by applicable law or agreed to in writing, software  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */
package com.xsm.lite.util;

/**
 * A simple light version of building an equals checking expression for an object.
 * 
 * @see #append(Object, Object)
 */
public class EqualsBuilder {
    
    //By default assume is equal.
    private boolean isEquals = true;

    /**
     * Only supported for Objects that have implemented equals().
     * Primitives will work as well here.
     * 
     * author Sony Mathew
     */
    public <T> EqualsBuilder append(T lhs, T rhs) {
        if (isEquals == false) {
            return this; //already false, no further.
        }
        if (lhs == rhs) {
            return this; //still equal, no further.
        }
        if (lhs == null || rhs == null) {
            isEquals = false;
            return this;
        }
        isEquals = lhs.equals(rhs);
        return this;
    }
    
    /**
     * See if 2 arrays of objects are equal.
     * 
     * Note: Primitive arrays will not invoke this method, 
     *  it will invoke the non-array equivalent and so 
     *      will return false if not the same object.
     * 
     * author Sony Mathew
     */
    public <T> EqualsBuilder append(T[] lhs, T[] rhs) {
        if (isEquals == false) {
            return this; //already false, no further.
        }        
        if (lhs == rhs) {
            return this;
        }
        if (lhs == null || rhs == null) {
            isEquals = false;
            return this;
        }
        if (lhs.length != rhs.length) {
            isEquals = false;
            return this;
        }
        for(int i=0;i<lhs.length;i++){
            append(lhs[i], rhs[i]);
        }        
        return this;
    }
    
    public boolean isEquals() {
        return this.isEquals;
    }
    
    /**
     * A Quick one time check to see if something is equal.
     * 
     * @see #append(T, T)
     * author Sony Mathew
     */
    public static <T> boolean isEquals(T lhs, T rhs) {
        EqualsBuilder eq = new EqualsBuilder();
        eq.append(lhs, rhs);
        return eq.isEquals();
    }
    
    /**
     * A Quick one time check to see if something is equal.
     * 
     * @see #append(T[], T[])
     * 
     * author Sony Mathew
     */
    public static <T> boolean isEquals(T[] lhs, T[] rhs) {
        EqualsBuilder eq = new EqualsBuilder();
        eq.append(lhs, rhs);
        return eq.isEquals();
    }
    
    /**
     * Checks if 2 objects are compatible for doing an equals check.
     * Checks if null, same type etc.
     * 
     * author Sony Mathew
     */
    public static boolean isCompatible(Object lhs, Object rhs) {
        if (lhs == rhs) {
            return true;
        }
        if (lhs == null || rhs == null) {
            return false;
        }
        if ( ! lhs.getClass().equals(rhs.getClass())) {
            return false;
        }        
        return true;
    }
}
